package com.hsgene.user.controller.organization;

import com.hsgene.common.exception.CommonErrorCode;
import com.hsgene.common.util.basic.SimpleStringUtils;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.support.LimitHelper;
import com.hsgene.common.util.support.OrderHelper;
import com.hsgene.common.util.support.Pagination;
import com.hsgene.user.condition.PositionCondition;
import com.hsgene.user.domain.Position;
import com.hsgene.user.dto.orginazation.PositionDto;
import com.hsgene.user.dto.orginazation.PositionIdsDto;
import com.hsgene.user.exception.OrganizationErrorCode;
import com.hsgene.user.service.CompanyService;
import com.hsgene.user.service.DepartmentService;
import com.hsgene.user.service.PositionService;
import com.hsgene.user.service.api.GeneratorService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description: 职位管理类
 * @projectName: hdas-geneshop-server
 * @package: com.hsgene.order.controller.organization
 * @author: maodi
 * @createDate: 2018/11/5 10:03
 * @version: 1.0
 * Copyright: Copyright (c) 2018
 */
@RestController
@RequestMapping("/v1.0/genetic/testing/positions")
public class PositionController {

    private static Logger LOGGER = LogManager.getLogger(PositionController.class);

    @Resource
    PositionService positionService;

    @Resource
    DepartmentService departmentService;

    @Resource
    GeneratorService generatorService;

    @Resource
    CompanyService companyService;

    /**
     * @param positionName 职位名称
     * @param departmentId 部门id
     * @param companyId    公司id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 职位插入去重
     * @author maodi
     * @createDate 2018/11/13 17:54
     */
    @GetMapping("insert/repeat")
    public ApiResult<NullObject> insertRepeat(@RequestParam("positionName") String positionName, @RequestParam
            ("companyId") String companyId, @RequestParam("departmentId") String departmentId) {
        try {
            if (StringUtils.isBlank(positionName)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int existDepartmentCount = departmentService.queryDepartmentById(departmentId).size();
            if (existDepartmentCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_EXIST);
            }
            int count = positionService.queryPositionCountByName(positionName, companyId, departmentId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_EXIST);
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.INSERT_POSITION_REPEAT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.INSERT_POSITION_REPEAT_IS_ERROR);
        }
    }

    /**
     * @param positionName 职位名称
     * @param companyId    公司id
     * @param departmentId 部门id
     * @param positionId   职位id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 职位修改去重
     * @author maodi
     * @createDate 2018/11/13 18:02
     */
    @GetMapping("update/repeat")
    public ApiResult<NullObject> updateRepeat(@RequestParam("positionName") String positionName, @RequestParam
            ("companyId") String companyId, @RequestParam("departmentId") String departmentId, @RequestParam
                                                      ("positionId") String positionId) {
        try {
            if (StringUtils.isBlank(positionId)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_ID_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(positionName)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int existDepartmentCount = departmentService.queryDepartmentById(departmentId).size();
            if (existDepartmentCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_EXIST);
            }
            int count = positionService.queryPositionCountByNameExcludeSelf(positionName, companyId, departmentId,
                    positionId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_EXIST);
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.UPDATE_POSITION_REPEAT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.UPDATE_POSITION_REPEAT_IS_ERROR);
        }
    }

    /**
     * @param positionId 职位id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.user.domain.Position>
     * @description 根据职位id获取职位信息出错
     * @author maodi
     * @createDate 2018/11/13 18:05
     */
    @GetMapping("{position_id}")
    public ApiResult<Position> getPositionByPositionId(@PathVariable("position_id") String positionId) {
        try {
            List<PositionDto> list = positionService.queryPositionById(positionId);
            if (list != null && list.size() > 0) {
                return ApiResult.succ(list.get(0));
            } else {
                return ApiResult.succ(null, "暂无数据");
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.QUERY_POSITION_BY_ID_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.QUERY_POSITION_BY_ID_IS_ERROR);
        }
    }

    /**
     * @param companyId    公司id
     * @param departmentId 部门id
     * @return com.hsgene.common.util.result.ApiResult<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
     * @description 根据公司id和部门id获取职位下拉框数据源
     * @author maodi
     * @createDate 2018/11/13 18:17
     */
    @GetMapping("select")
    public ApiResult<List<Map<String, Object>>> select(@RequestParam("companyId") String companyId, @RequestParam
            ("departmentId") String departmentId) {
        try {
            List<Map<String, Object>> list = positionService.selectPosition(companyId, departmentId);
            if (list != null && list.size() > 0) {
                return ApiResult.succ(list);
            } else {
                return ApiResult.succ();
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.SELECT_POSITION_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.SELECT_POSITION_IS_ERROR);
        }
    }

    /**
     * @param page           页数
     * @param size           每页数量
     * @param positionName   职位名称
     * @param departmentName 部门名称
     * @param companyName    公司名称
     * @param sort           修改时间排序规则
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.support.Pagination<com.hsgene.user.dto
     * .orginazation.PositionDto>>
     * @description 查询职位信息/职位列表
     * @author maodi
     * @createDate 2018/11/7 10:07
     */
    @GetMapping
    public ApiResult<Pagination<PositionDto>> queryPosition(
            @RequestParam("page") Integer page,
            @RequestParam("size") Integer size,
            @RequestParam(name = "positionName", required = false) String positionName,
            @RequestParam(name = "departmentName", required = false) String departmentName,
            @RequestParam(name = "companyName", required = false) String companyName,
            @RequestParam(name = "sort", required = false, defaultValue = "desc") String sort) {
        try {
            if (page == null) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NULL);
            }
            if (!SimpleStringUtils.isPositiveInteger(page.toString())) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NOT_POSITIVE_INTEGER);
            }
            if (size == null) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NULL);
            }
            if (!SimpleStringUtils.isPositiveInteger(size.toString())) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NOT_POSITIVE_INTEGER);
            }
            sort = sort.toLowerCase();
            if (!"desc".equalsIgnoreCase(sort) && !"asc".equalsIgnoreCase(sort)) {
                return ApiResult.fail(CommonErrorCode.SORT_ORDER_IS_ERROR);
            }
            PositionCondition condition = new PositionCondition();
            condition.setPositionName(positionName);
            condition.setDepartmentName(departmentName);
            condition.setCompanyName(companyName);
            LimitHelper limitHelper = LimitHelper.create(page, size);
            condition.setLimitHelper(limitHelper);
            OrderHelper orderHelper = OrderHelper.create("gtop.update_date_time", sort);
            condition.setOrderHelper(orderHelper);
            List<PositionDto> result = positionService.queryPositionByCondition(condition);
            addNum(result, page, size);
            int totalCount = positionService.queryPositionCountByCondition(condition);
            Pagination pagination = Pagination.newInstance(limitHelper, totalCount, result);
            return ApiResult.succ(pagination);
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.QUERY_POSITION_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.QUERY_POSITION_IS_ERROR);
        }
    }

    /**
     * @param position 职位信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 新增职位信息
     * @author maodi
     * @createDate 2018/11/7 10:13
     */
    @PostMapping
    public ApiResult<NullObject> insertPosition(@RequestBody Position position) {
        try {
            String positionName = position.getPositionName();
            if (StringUtils.isBlank(positionName)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_NOT_NULL);
            }
            String companyId = position.getCompanyId();
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            String departmentId = position.getDepartmentId();
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int existDepartmentCount = departmentService.queryDepartmentById(departmentId).size();
            if (existDepartmentCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_EXIST);
            }
            int matchCount = departmentService.queryCountByDepartmentIdAndCompanyId(departmentId, companyId);
            if (matchCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_NOT_MATCH_COMPANY_ID);
            }
            int count = positionService.queryPositionCountByName(positionName, companyId, departmentId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_EXIST);
            }
            String id = generatorService.getGenerator("", "").getData().getSerialNumber();
            position.setId(id);
            Date date = new Date();
            position.setCreateDateTime(date);
            position.setUpdateDateTime(date);
            positionService.insertPosition(position);
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.INSERT_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.INSERT_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param positionId 职位id
     * @param position   职位信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 修改职位信息
     * @author maodi
     * @createDate 2018/11/7 10:19
     */
    @PutMapping("{position_id}")
    public ApiResult<NullObject> updatePosition(@PathVariable("position_id") String positionId, @RequestBody Position
            position) {
        try {
            if (StringUtils.isBlank(positionId)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_ID_IS_NOT_NULL);
            }
            position.setId(positionId);
            String positionName = position.getPositionName();
            if (StringUtils.isBlank(positionName)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_NOT_NULL);
            }
            String companyId = position.getCompanyId();
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            List<PositionDto> positionDtoList = positionService.queryPositionById(positionId);
            String oldCompanyId = null;
            PositionDto dto = null;
            if (positionDtoList != null && positionDtoList.size() > 0) {
                dto = positionDtoList.get(0);
                oldCompanyId = dto.getCompanyId();
            }
            if (oldCompanyId == null || !companyId.equals(oldCompanyId)) {
                return ApiResult.fail(OrganizationErrorCode.CAN_NOT_UPDATE_COMPANY);
            }
            String departmentId = position.getDepartmentId();
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            String oldDepartmentId = null;
            if (dto != null) {
                oldDepartmentId = dto.getDepartmentId();
            }
            if (oldDepartmentId == null || !departmentId.equals(oldDepartmentId)) {
                return ApiResult.fail(OrganizationErrorCode.CAN_NOT_UPDATE_DEPARTMENT);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int existDepartmentCount = departmentService.queryDepartmentById(departmentId).size();
            if (existDepartmentCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_EXIST);
            }
            int matchCount = departmentService.queryCountByDepartmentIdAndCompanyId(departmentId, companyId);
            if (matchCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_NOT_MATCH_COMPANY_ID);
            }
            int count = positionService.queryPositionCountByNameExcludeSelf(positionName, companyId, departmentId,
                    positionId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_NAME_IS_EXIST);
            }
            int queryCount = positionService.queryPositionById(positionId).size();
            if (queryCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_IS_NOT_EXIST);
            }
            position.setUpdateDateTime(new Date());
            int returnCount = positionService.updatePosition(position);
            if (returnCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.UPDATE_POSITION_IS_ERROR);
            } else if (returnCount > 1) {
                return ApiResult.succ(null, OrganizationErrorCode.POSITION_IS_MULTI.getDescription());
            } else {
                return ApiResult.succ();
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.UPDATE_POSITION_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.UPDATE_POSITION_IS_ERROR);
        }
    }

    /**
     * @param positionId 职位id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 删除职位信息
     * @author maodi
     * @createDate 2018/11/7 10:26
     */
    @DeleteMapping("{position_id}")
    public ApiResult<NullObject> deletePosition(@PathVariable("position_id") String positionId) {
        try {
            if (StringUtils.isBlank(positionId)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_ID_IS_NOT_NULL);
            }
            int queryCount = positionService.queryPositionById(positionId).size();
            if (queryCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_HAVE_BEEN_DELETED);
            }
            int usedCount = positionService.queryOperationAccountCountByPositionId(positionId);
            if (usedCount > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_IS_USED_CAN_NOT_DELETE);
            }
            Position position = new Position();
            position.setId(positionId);
            position.setUpdateDateTime(new Date());
            int returnCount = positionService.deletePosition(position);
            if (returnCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DELETE_POSITION_IS_ERROR);
            } else if (returnCount > 1) {
                return ApiResult.succ(null, OrganizationErrorCode.POSITION_IS_MULTI.getDescription());
            } else {
                return ApiResult.succ();
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.DELETE_POSITION_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.DELETE_POSITION_IS_ERROR);
        }
    }

    /**
     * @param positionIdsDto 职位id数组字符串实体
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 职位批量删除
     * @author maodi
     * @createDate 2018/11/14 8:55
     */
    @DeleteMapping
    public ApiResult<NullObject> deletePositionMulti(@RequestBody PositionIdsDto positionIdsDto) {
        String positionIdsStr = positionIdsDto.getPositionIds();
        try {
            if (StringUtils.isBlank(positionIdsStr)) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_IDS_IS_NOT_NULL);
            }
            String[] positionIds = positionIdsStr.split(",");
            if (positionIds == null || positionIds.length < 1) {
                return ApiResult.fail(OrganizationErrorCode.POSITION_IDS_IS_NOT_NULL);
            }
            positionService.deletePositionMulti(positionIds);
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.DELETE_POSITION_MULTI_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.DELETE_POSITION_MULTI_IS_ERROR);
        }
    }

    /**
     * @param list 职位列表
     * @param page 页数
     * @param size 每页数量
     * @return void
     * @description 为职位列表添加序号
     * @author maodi
     * @createDate 2018/11/8 10:30
     */
    private void addNum(List<PositionDto> list, int page, int size) {
        int start = (page - 1) * size + 1;
        for (PositionDto positionDto : list) {
            positionDto.setNum(start++);
        }
    }

}
